package cohesion;

#perl cohesion.pl -s ~/corpus/supervised_data/LWG/eng.p20.lwg.TRAIN.txt -t ~/corpus/supervised_data/LWG/hnd.p20.lwg.TRAIN.txt -d ~/corpus/supervised_data/LWG/Dep/eng.p20.depen.lwg.TRAIN.txt -a ~/corpus/supervised_data/LWG/Align/align.p20.TRAIN.eval
#perl cohesion.pl -s ~/corpus/supervised_data/eng_5k.p20.TRAIN.txt -t ~/corpus/supervised_data/hnd_5k.p20.TRAIN.txt -d ~/corpus/supervised_data/Dep/eng.5k.depen.TRAIN.txt -a ~/corpus/supervised_data/Align/align.5k.TRAIN.eval

use vaaneeConfig qw(%C);
use Varg qw(%C);
use DepTree qw(%C);
use Align qw(%C);
use Features qw(%dbs %C);  

use AlignBeam qw(%C);
use Parameters qw(%C);
use LocalBeam qw(%C);

use PQ qw();

@ISA = qw(Exporter);
@EXPORT = qw();
@EXPORT_OK = qw(%dbs %C);


sub new {
	my($corpus) = {};
	my($classname) = shift;
	bless($corpus);

	my($srcFile) = shift;
	my($tgtFile) = shift;
	my($srcDep) = shift;
	my($srcAlign) = shift;

	my($line);

# Temporary variables
	my($a,$b,$c);
	my($sennum,$word,@words,@temparr,$tempsca);

	my($Varg,$Align,$AlignBeam,$Features,$Dep);

	my(@tempalns);
	my($i,$j,$k);
	my($srcword,$tgtword);
	my(%sentencenums);

	if($srcFile) {
		print STDERR "Loading Sens $srcFile \n";
		$corpus->loadSen('SSen',$srcFile);
	}

	if($tgtFile) {
		print STDERR "Loading Tgt Sens\n";
		$corpus->loadSen('TSen',$tgtFile);
	}

	if($srcDep) {
		print STDERR "Loading Deps\n";
		$corpus->loadDep('SDep',$srcDep);
	}

	if($srcAlign) 
	{
		print STDERR "Loading Aligns\n";
		$corpus->loadAlign('Align',$srcAlign);
	}

	return $corpus;
}

sub loadSen {

	my($corpus) = shift;
	my($type) = shift;
	my($file) = shift;
	my($flag) = "l";

	open(FILE,$file);

	my @lines = <FILE>;
#print @lines;
	chomp(@lines);

	my $no_lines = @lines;
	my $senNum ;
	my $i=0;
	my $wordnum = 0;

	if($flag eq "i")
	{
		for($i=0; $i < $no_lines; $i++)
		{
			if($lines[$i] =~ /^\s*$/)
			{
			}
			elsif($lines[$i] =~ /^([0-9]+)$/)
			{
				$senNum = $1;
				$wordnum = 0;
			}
			else
			{
				my($word_POS_root,@features) = split(/\t/,$lines[$i]);

				my($word,$pos,$root) = split(/_/,$word_POS_root);
				$corpus->{$senNum}->{$type}->[$wordnum]->{'word'} = $word;
				$corpus->{$senNum}->{$type}->[$wordnum]->{'pos'} = $pos;
				$corpus->{$senNum}->{$type}->[$wordnum]->{'root'} = $root;

# For 'prep' and 'aux' of the word. 

				my $feature;
				foreach $feature (@features)
				{
					my ($feat,$value) = split(/:/,$feature); 
					$corpus->{$senNum}->{$type}->[$wordnum]->{$feat} = $value;
				}
				$wordnum++;
			}
		}
	}
	else
	{
		for($i=0; $i < $no_lines; $i++)
		{
#			print $lines[$i]."\n";
			$senNum = $i + 1;
			$wordnum = 0;
			@words = split(/\s+/,$lines[$i]);
			foreach $word_POS_root (@words)
			{
				my($word,$pos,$root) = split(/_/,$word_POS_root);
#	print $word." ";
				$corpus->{$senNum}->{$type}->[$wordnum]->{'word'} = $word;
				$corpus->{$senNum}->{$type}->[$wordnum]->{'pos'} = $pos;
				$corpus->{$senNum}->{$type}->[$wordnum]->{'root'} = $root;

				$wordnum++;
			}
		}
	}
}

sub loadDep {

	my($corpus) = shift;
	my($type) = shift;
	my($depfname) = shift;
	my($senNum);

	open(DEPTREE,$depfname);
	my($depline);
	my($procsen) = 0;
	my($senidx,$rootpos) ;
	my($Senid) = 1;

	while($depline=<DEPTREE>)
	{
		chomp($depline);
		$senNum = $depline;

		my($Dep) = new DepTree;

		my $line = <DEPTREE>;
		chomp($line);
		($temp,$root_pos) = split(/\s+/,$line);

		$Dep->addroot($root_pos);

		while(!($line=~/^\s*$/))
		{
			$line = <DEPTREE>; chomp($line);

			if($line=~/^[#](.*?) (.*)$/)
			{
				$word_num = $1;
				$Dep->createnode($word_num);

				$line = <DEPTREE>;  chomp($line);
			}
			elsif($line=~/att #(.*)/)
			{
				$Dep->addattch($word_num,$1);
			}
			if($line=~/^[&](.*?)$/)   #Ask Karthik to check this
			{
				$word_num = $1;

				$line = <DEPTREE>;  chomp($line);

				$Dep->createnode($word_num);
			}
			elsif($line=~/con #(.*)/)
			{
				$Dep->addattch($word_num,$1);
			}
		}

		$corpus->{$senNum}->{$type} = $Dep;
	}
}

sub loadAlign {
	my($corpus) = shift;
	my($type) = shift;
	my($file) = shift;

	open(FILE,$file) || die "Can't open $file\n";
	my @lines = <FILE>;

	my($line);
	my $no_lines = @lines;
	my $senNum;
	my $i=0;
	my $wordnum = 0;
	my $alignments;

	for($i=0; $i < $no_lines; $i++)
	{
		$line = $lines[$i]; 
		($senNum,$srcword,$tgtword) = split(/\s+/,$line);
		$alignments->{$senNum}->{"$srcword $tgtword"} = 1;

	}

	foreach $senNum (keys %{$alignments}) {
		my $Align = new Align;

		foreach $line (keys %{$alignments->{$senNum}}) {
			($srcword,$tgtword) = split(/\s+/,$line);
			$Align->addalign($srcword,$tgtword);
		}

		$corpus->{$senNum}->{$type} = $Align; 

	}
}


sub getnodessubtree {
	my($sword) = shift;
	my($engsen) = shift;
	my($hinsen) = shift;
	my($Dep) = shift;
	my($Align)= shift;
	my($src_hash) = shift;

	foreach $child  (@{$Dep->[$sword]->{'attch'}})
	{
#               print $child,"\n";
		$src_hash->{ $child } = 1;
		&getnodessubtree($child,$engsen,$hinsen,$Dep,$Align,$src_hash);
	}
	$src_hash->{ $sword } = 1;


}

sub cohesion
{
	my($corpus) = shift;
	my($senNum) = shift;

#	print "Here --> ",$corpus->{$senNum}->{'TSen'}->[0]->{'word'},"\n";
#	print "Here --> $senNum \n";
	my($Varg,$Dep);
	my($engsen,$hinsen);
	my($GoldAlign,$GenAlign,$GenAlign2);
	my($Beam,$TempBeam);
	my($LFeatures,$score);
	my($localbeam,%localbeams);
	my($k,$m,$n,$p,$i);
	my($minScore,$minPosition);
	my($hinwordpos);
	my($verbnum,$argnum);
	my($LFeatures,$GenFeatures);
	my($nengwords,$nhinwords);

	$Dep = $corpus->{$senNum}->{'SDep'};
#	print $Dep,"\n";
	$engsen = $corpus->{$senNum}->{'SSen'};
	$nengwords = @{$engsen};
	$hinsen = $corpus->{$senNum}->{'TSen'};
	$nhinwords = @{$hinsen};
	$Align = $corpus->{$senNum}->{'Align'};

#	print $engsen,"\n";
#	print $corpus->{$senNum}->{'SSen'},"\n";
	for($i=0;$i<@{$corpus->{$senNum}->{'SSen'}};$i++) # Getting the lowest and highest node of the tgt side with which the sub-tree is aligned
	{
		%src_hash = ();
		&getnodessubtree($i,$engsen,$hinsen,$Dep,$Align,\%src_hash);
		$src_hash->{ $i } = 0;
#		print "\nFor node $i following are the subtree nodes:\n";
		foreach $src ((sort {$a<=>$b} keys %src_hash))
		{
#			print "sub-tree --> ",$src,"\n";
			$corpus->{$senNum}->{'SSen'}->[$i]->{'src_hash'}->{$src} = 1;
		}
#		$corpus->{$senNum}->{'SSen'}->[$i]->{'src_hash'} = \%src_hash;

		$tgt_small = 10000;
		$tgt_high = -1;	
		foreach $src ((sort {$a<=>$b} keys %src_hash))
		{
			foreach $tgt (@{$Align->{'aln'}->[$src]})
			{
				if($tgt_small > $tgt)
				{
					$tgt_small = $tgt;
				}
				if($tgt_high < $tgt)
				{
					$tgt_high = $tgt;
				}
			}
		}
		$corpus->{$senNum}->{'SSen'}->[$i]->{'tgt_small'} = $tgt_small;
		$corpus->{$senNum}->{'SSen'}->[$i]->{'tgt_high'} = $tgt_high;
	}

	for($i=0;$i<@{$corpus->{$senNum}->{'SSen'}};$i++)
	{
		$par_small = 10000;
		$par_high = -1;
		%tgtwords = ();
		%mapping = ();
		foreach $tgt (@{$Align->{'aln'}->[$i]})
		{
			if($par_small > $tgt)
			{
				$par_small = $tgt;
			}
			if($par_high < $tgt)
			{
				$par_high = $tgt;
			}
		}
		%child_hash = ();
		foreach $child  (@{$Dep->[$i]->{'attch'}})
		{
			$child_hash { $child } = 1;
			$child_small = $corpus->{$senNum}->{'SSen'}->[$child]->{'tgt_small'};
			$child_high = $corpus->{$senNum}->{'SSen'}->[$child]->{'tgt_high'};
			if((($child_small < $par_small)  and  ($par_small < $child_high)) or (($child_small < $par_high) and ($par_high < $child_high)) or (($par_small < $child_small) and ( $par_high > $child_high)))
			{
				if($par_small != 10000 and $child_small != 10000)
				{
					$src_sen = "";
					$tgt_sen = "";
					for ($s = 0; $s < @{$corpus->{$senNum}->{'SSen'}};$s++)
					{
						$src_sen = $src_sen.$corpus->{$senNum}->{'SSen'}->[$s]->{'word'}." ";
					}
					for ($s = 0; $s < @{$corpus->{$senNum}->{'TSen'}};$s++)
					{
						$tgt_sen = $tgt_sen.$corpus->{$senNum}->{'TSen'}->[$s]->{'word'}." ";
					}
					print "------------------------------------------------------------\n\n\n";
					print "Sentence: $senNum\n";
					print "Source Sen is: ".$src_sen,"\n";
					print "Tgt Sen is: ".$tgt_sen,"\n\n";
					print "Issue: \"".$corpus->{$senNum}->{'SSen'}->[$i]->{'word'}."/".$corpus->{$senNum}->{'SSen'}->[$i]->{'pos'}."\" breaks projectivity of \"";
					print $corpus->{$senNum}->{'SSen'}->[$child]->{'word'}."/".$corpus->{$senNum}->{'SSen'}->[$child]->{'pos'}."\" ( ";
					for ($t = 0; $t < @{$corpus->{$senNum}->{'SSen'}};$t++)
					{
						if($corpus->{$senNum}->{'SSen'}->[$child]->{'src_hash'}->{$t} == 1)
						{
							print $corpus->{$senNum}->{'SSen'}->[$t]->{'word'}," ";
						}
					}
					print ")\n";
					%tree = ();
					foreach $child  (@{$Dep->[$i]->{'attch'}})
					{
						$tree{ $child } = 1;
					}
					$tree{ $i } = 2;
					$k = 1;
					print "Structure:";
					for($l = 0; $l < @{$corpus->{$senNum}->{'SSen'}}; $l++)
					{
						if($tree{ $l } == 1)
						{
							print $corpus->{$senNum}->{'SSen'}->[$l]->{'pos'}."~$k ";
							$k++;
						}
						elsif($tree{ $l } == 2)
						{
							print $corpus->{$senNum}->{'SSen'}->[$l]->{'pos'}."* ";
						}
					}
					print "\n";
					print "\n";
					print "Parent word alignments::  ";
					foreach $tgt (sort {$a<=>$b} @{$Align->{'aln'}->[$i]})
					{
						print $tgt.":".$corpus->{$senNum}->{'TSen'}->[$tgt]->{'word'}," ";
					}
					print "\n";
					print "Child subtree alignment:  ";
					$child_small = $corpus->{$senNum}->{'SSen'}->[$child]->{'tgt_small'};
					$child_high = $corpus->{$senNum}->{'SSen'}->[$child]->{'tgt_high'};
					for( $t = $child_small; $t <= $child_high; $t++)
					{
						print $t.":".$corpus->{$senNum}->{'TSen'}->[$t]->{'word'}." ";
					}
					print "\n";
					print "\n";
					for ($t = 0; $t < @{$corpus->{$senNum}->{'SSen'}};$t++)
					{
						if($corpus->{$senNum}->{'SSen'}->[$child]->{'src_hash'}->{$t} == 1)
						{
							print $corpus->{$senNum}->{'SSen'}->[$t]->{'word'}." : ";
							foreach $tgt (sort {$a<=>$b} @{$Align->{'aln'}->[$t]})
							{
								print $tgt.":".$corpus->{$senNum}->{'TSen'}->[$tgt]->{'word'}," ";
							}
							print "\n";
						}
					}
					print "\n";
					print "Alignment Corrections:\n";
					print "COMMENTS:\n";
					print "\n";
					print "------------------------------------------------------------\n\n\n";
				}
			}
			else
			{
				
				%tree = ();
				foreach $child  (@{$Dep->[$i]->{'attch'}})
				{
					$tree{ $child } = 1;
				}
				$tree{ $i } = 2;
				$k = 1;
				for($l = 0; $l < @{$corpus->{$senNum}->{'SSen'}}; $l++)
				{
					if($tree{ $l } == 1)
					{
						my $tgt_pre = 10000;
						foreach $tgt (@{$Align->{'aln'}->[$l]})
						{
							if($tgt_pre > $tgt)
							{
								$tgt_pre = $tgt;
							}
						}
						if(@{$Align->{'aln'}->[$l]}!=0)  # If there is a alignements for $src
						{
							$tgtwords { $tgt_pre } = $srcwords{ $l };
							$mapping { $tgt_pre } = $mapping { $tgt_pre }.$src."|".$k."_";
						}
						print STDERR $corpus->{$senNum}->{'SSen'}->[$l]->{'pos'}."~$k ";
						$k++;
					}
					elsif($tree{ $l } == 2)
					{
						my $tgt_pre = 10000;
						foreach $tgt (@{$Align->{'aln'}->[$l]})
						{
							if($tgt_pre > $tgt)
							{
								$tgt_pre = $tgt;
							}
						}
						if(@{$Align->{'aln'}->[$l]}!=0)  # If there is a alignements for $src
						{
							$tgtwords { $tgt_pre } = $srcwords{ $src };
							$mapping { $tgt_pre } = $mapping { $tgt_pre }.$src."|".$k."_";
						}
						print STDERR $corpus->{$senNum}->{'SSen'}->[$l]->{'pos'}."* ";
					}
				}
				my $tgt_array = "";
				foreach $tgt ((sort {$a<=>$b} keys %tgtwords))
				{
					chop($mapping{ $tgt });
					my @maps = split(/_/,$mapping{ $tgt });
					my $map1;
					foreach $map1 (@maps)
					{
						my $num;
						($map,$num) = split(/\|/,$map1);
						if($map == $sword) # it is root
						{
							if($tgt_array.$engsen->[$map]->{'pos'} =~ /^[NV]/ )
							{
								$tgt_array = $tgt_array.$engsen->[$map]->{'pos'}."&_";
							}
						}
						else
						{
							if($tgt_array.$engsen->[$map]->{'pos'} =~ /^[NV]/ )
							{
								$tgt_array = $tgt_array.$engsen->[$map]->{'pos'}."~".$num."_";
							}
						}
					}
				}
				print STDERR $tgt_array;
				print STDERR "\n";
			}
		}
		$size = scalar(keys %child_hash);
		$flag1 = -1;
		$flag2 = -1;
		if($size > 1)
		{
			for($k = 0; $k < @{$corpus->{$senNum}->{'SSen'}}; $k++)
			{
				if( $child_hash { $k } == 1)
				{
					if($flag1 == -1)
					{
						$flag1 = $k;
					}
					else
					{
						$flag2 = $k;
					}
				}
				if($flag1 != -1 and $flag2 != -1)
				{
					$child_small1 = $corpus->{$senNum}->{'SSen'}->[$flag1]->{'tgt_small'};
					$child_high1 = $corpus->{$senNum}->{'SSen'}->[$flag1]->{'tgt_high'};
					$child_small2 = $corpus->{$senNum}->{'SSen'}->[$flag2]->{'tgt_small'};
					$child_high2 = $corpus->{$senNum}->{'SSen'}->[$flag2]->{'tgt_high'};
					if((($child_small1 < $child_small2) and ($child_small2 < $child_high1)) or (($child_small1 < $child_high2) and ($child_high2 < $child_high1)) or (($child_small2 < $child_small1) and ($child_high2 > $child_high1 )))
					{
						if($child_high1 != -1 and $child_high2 != -1)
						{
							$src_sen = "";
							$tgt_sen = "";
							for ($s = 0; $s < @{$corpus->{$senNum}->{'SSen'}};$s++)
							{
								$src_sen = $src_sen.$corpus->{$senNum}->{'SSen'}->[$s]->{'word'}." ";
							}
							for ($s = 0; $s < @{$corpus->{$senNum}->{'TSen'}};$s++)
							{
								$tgt_sen = $tgt_sen.$corpus->{$senNum}->{'TSen'}->[$s]->{'word'}." ";
							}
							print "Source Sen is: ".$src_sen,"\n";
							print "Tgt Sen is: ".$tgt_sen,"\n";
							print "The nodes $flag1".$corpus->{$senNum}->{'SSen'}->[$flag1]->{'word'}." ".$corpus->{$senNum}->{'SSen'}->[$flag1]->{'pos'}." and $flag2 ".$corpus->{$senNum}->{'SSen'}->[$flag2]->{'word'}." ".$corpus->{$senNum}->{'SSen'}->[$flag2]->{'pos'}." of sentence $senNum are OVERLAP\n";
							print "The alignments of node $flag1 are:\n";
							foreach $tgt (@{$Align->{'aln'}->[$flag1]})
							{
								print $tgt.":".$corpus->{$senNum}->{'TSen'}->[$tgt]->{'word'},"\t";
							}
							print "\n";
							print "The alignments of node $flag2 are:\n";
							foreach $tgt (@{$Align->{'aln'}->[$flag2]})
							{
								print $tgt.":".$corpus->{$senNum}->{'TSen'}->[$tgt]->{'word'},"\t";
							}
							print "\n";
							print "Child_small1 Alignments are \n";
							print $child_small1.":".$corpus->{$senNum}->{'TSen'}->[$child_small1]->{'word'};
							print "\n";
							print "Child_high1 Alignments are \n";
							print $child_high1.":".$corpus->{$senNum}->{'TSen'}->[$child_high1]->{'word'};
							print "\n";
							print "Child_small2 Alignments are \n";
							print $child_small2.":".$corpus->{$senNum}->{'TSen'}->[$child_small2]->{'word'};
							print "\n";
							print "Child_high2 Alignments are \n";
							print $child_high2.":".$corpus->{$senNum}->{'TSen'}->[$child_high2]->{'word'};
							print "\n";
							print "\n";
						}
					}
					$flag1 = -1;
					$flag2 = -1;
				}
			}
		}
	}

#			print "The node $i of Sentence $senNum is not cohesive $par_small --> $par_high ||| $child_high --> $child_small --------------> $child \n";

=cut
		$pres_small = 9999;
	$pres_high = -4;	
	foreach $pres (@{$Align->{'aln'}->[$i]})
	{
#			print "Here $src -- >$pres\n";
		if($pres_small > $pres)
		{
			$pres_small = $pres;
		}
		if($pres_high < $pres)
		{
			$pres_high = $pres;
		}
	}
	if((($tgt_small < $pres_small) and ($pres_small < $tgt_high)) or (($tgt_small < $pres_high) and ( $pres_high < $tgt_high)))
	{
#			print "The node $i of Sentence $senNum is not cohesive $pres_small --> $tgt_small ||| $pres_high --> $tgt_high \n";
	}
	else
	{
	}
}

=cut


=cut	
for($i=0;$i<@{$corpus->{$senNum}->{'SSen'}};$i++)
{
	@out_stree = ();
	for($j = 0; $j < @{$corpus->{$senNum}->{'SSen'}}; $j++)
	{
		$out_stree[$j] = 0;
	}
#		print $corpus->{$senNum}->{'SSen'}->[$i]->{'src_hash'};
	$src_hash = $corpus->{$senNum}->{'SSen'}->[$i]->{'src_hash'};
#		print "\nFor node $i following are the subtree nodes:\n";
	foreach $src (sort {$a<=>$b} keys %$src_hash)
	{
#			print $src,"\n";
		$out_stree[$src] = 1;
	}
#		for($j = 0; $j < @{$corpus->{$senNum}->{'SSen'}}; $j++)
#		{
#			print $out_stree[$j],"\n";
#		}
	$tgt_small =  $corpus->{$senNum}->{'SSen'}->[$i]->{'tgt_small'};
	$tgt_high = $corpus->{$senNum}->{'SSen'}->[$i]->{'tgt_high'} ;
#		print "For sentence $i -->\n";
#		print $tgt_high,"\n";
#		print $tgt_small,"\n";
	for($j = 0; $j < @{$corpus->{$senNum}->{'SSen'}}; $j++)
	{
		if($out_stree[$j] == 0)
		{
			foreach $tgt (@{$Align->{'aln'}->[$j]})
			{
				if($tgt < $tgt_small or $tgt > $tgt_high)
				{
				}
				else
				{
					print "The node $i of Sentence $senNum is not cohesive with $j\n";
				}
			}
		}
	}
}
=cut

}

1;
